
package com.lmx.persistence.service;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lmx.common.constants.CommonConstants;
import com.lmx.common.context.ActionContextHolder;
//import com.lmx.repoDomain.model.*;
//huibati
import com.lmx.repoDomain.tmodel.Privilege;
import com.lmx.repoDomain.tmodel.Role;
import com.lmx.repoDomain.tmodel.RolePrivilege;

/**
 * #{description}
 *
 * @author Administrator
 * @version 1.00
 */
@Service
@Scope("prototype")
public class RoleService<T> {
	private Log logger = LogFactory.getLog(this.getClass());

	@PersistenceContext
	private EntityManager em;
	@Resource(name = "jdbcTemplate")
	private JdbcTemplate jdbcTemplate;

	@Autowired
	protected GenericService dslJpaService;

	/**
	 * 获取后台管理角色列表
	 * 
	 * @return
	 */
	public List<Map<String, Object>> getBackRoleList() {

		logger.debug("获取后台管理角色列表");

		List<Map<String, Object>> roleList = new ArrayList<Map<String, Object>>();

		String query = "select r from Role r where r.code not in ('reg-enterprises','reg-customer_service') and r.delStatus != 1";

		// 获取用户列表
		Query qu = (Query) this.em.createQuery(query);
		List resultList = qu.getResultList();

		for (int i = 0; i < resultList.size(); i++) {
			Role role = (Role) resultList.get(i);
			Map<String, Object> roleMap = new HashMap<String, Object>();

			String code = role.getCode();
			roleMap.put("roleCode", code == null ? code = "" : code);

			String name = role.getName();
			roleMap.put("roleName", name == null ? name = "" : name);

			roleList.add(roleMap);
		}

		return roleList;
	}

	/**
	 * 获取角色列表
	 * 
	 * @param values
	 * @return
	 */
	public List<Map<String, Object>> getRoleList(Map<String, Object> values) {

		logger.debug("获取角色列表");

		List<Map<String, Object>> roleList = new ArrayList<Map<String, Object>>();

		String query = "select r from Role r where r.delStatus != 1";

		String roleName = (String) values.get("roleName");
		if (roleName != null && !roleName.isEmpty()) {
			query = query + " and r.name like '%" + roleName + "%'";
		}

		// 获取角色列表
		Query qu = (Query) this.em.createQuery(query);
		qu.setMaxResults((int) values.get("size"));
		qu.setFirstResult((int) values.get("pageNum"));
		List resultList = qu.getResultList();

		for (int i = 0; i < resultList.size(); i++) {
			Role role = (Role) resultList.get(i);
			Map<String, Object> roleMap = new HashMap<String, Object>();

			String roleID = role.getId().toString();
			roleMap.put("roleID", roleID);// 角色id

			String roleCode = role.getCode();
			roleMap.put("roleCode", roleCode == null ? roleCode = "" : roleCode);// 角色code

			String roleNameStr = role.getName();
			roleMap.put("roleName", roleNameStr == null ? roleNameStr = "" : roleNameStr);// 角色名称

			String remark = role.getRemark();
			roleMap.put("remark", remark == null ? remark = "" : remark);// 备注

			Collection<Privilege> privileges = role.getPrivileges();
			roleMap.put("privileges", privileges);// 权限

			roleList.add(roleMap);
		}

		return roleList;
	}

	/**
	 * 获取角色列表总条数
	 * 
	 * @param values
	 * @return
	 */
	public int getRoleListCount(Map<String, Object> values) {

		logger.debug("获取角色列表总条数");

		String query = "select count(r.id) from Role r where r.delStatus != 1";

		String roleName = (String) values.get("roleName");
		if (roleName != null && !roleName.isEmpty()) {
			query = query + " and r.name like '%" + roleName + "%'";
		}

		int count = (int) (long) this.em.createQuery(query).getSingleResult();

		return count;
	}

	/**
	 * 增加角色
	 * 
	 * @return
	 */
	@Transactional
	public void addRole(Role role) {

		logger.debug("增加角色");

		role.setDelStatus((short) 0);

		dslJpaService.setEntityClass(Role.class);
		dslJpaService.create(role);

	}

	/**
	 * 获取角色详情
	 * 
	 * @return
	 */
	public Role getRole(Role role) {

		logger.debug("获取角色详情");

		Role result = new Role();

		Long roleID = role.getId();
		if (roleID != null) {
			result = this.em.find(Role.class, roleID);
		}

		String roleCode = role.getCode();
		if (roleCode != null && !roleCode.isEmpty()) {
			List list = this.em.createQuery("select r from Role r where r.code = ?1").setParameter(1, roleCode)
					.getResultList();
			if (list.size() > 0) {
				result = (Role) list.get(0);
			}
		}

		String roleName = role.getName();
		if (roleName != null && !roleName.isEmpty()) {
			List list = this.em.createQuery("select r from Role r where r.name = ?1").setParameter(1, roleName)
					.getResultList();
			if (list.size() > 0) {
				result = (Role) list.get(0);
			}
		}

		return result;
	}

	/**
	 * 删除角色
	 * 
	 * @param roleID
	 * @return
	 */
	@Transactional
	public void deleteRole(long roleID) {

		logger.debug("删除角色");
		String query = "update Role r set r.delStatus = ?1 where r.id = ?3";

		this.em.createQuery(query).setParameter(1, (short) 1)// 已删除
				.setParameter(3, roleID).executeUpdate();

	}

	/**
	 * 修改角色信息
	 * 
	 * @return
	 */
	@Transactional
	public void updateRoleInfo(Role role) {

		logger.debug("修改角色信息");
		String query = "update Role r set r.code = ?1 , r.name = ?2 , r.remark = ?3 where r.id = ?4";

		// 修改角色信息
		this.em.createQuery(query).setParameter(1, role.getCode()).setParameter(2, role.getName())
				.setParameter(3, role.getRemark()).setParameter(4, role.getId()).executeUpdate();
	}

	/**
	 * 获取角色权限列表
	 * 
	 * @param roleID
	 * @return
	 */
	public List getRolePrivilegeList(long roleID) {

		logger.debug("获取角色权限列表");

		String query = "SELECT " + "f.ID AS id," + "f.functionname AS showName," + "f.functioncode AS code,"
				+ "f.functiontype AS type," + "f.functionlevel AS level," + "f.functionorder AS privilegeOrder,"
				+ "f.remark AS remark," + "f.parentfunctionid AS pID," + "f.mo_menuname AS moName," + "rf.id AS rpID "
				+ "FROM " + "t_s_role_function rf," + "t_s_function f " + "WHERE rf.del_status = '0' "
				+ "AND f.del_status = '0' " + "AND rf.function_id = f.ID " + "AND f.functionlevel = '1' "
				+ "AND rf.role_id = '" + roleID + "'";
		String query1 = "SELECT " + "f.ID AS id," + "f.functionname AS showName," + "f.functioncode AS code,"
				+ "f.functiontype AS type," + "f.functionlevel AS level," + "f.functionorder AS privilegeOrder,"
				+ "f.remark AS remark," + "f.parentfunctionid AS pID," + "f.mo_menuname AS moName," + "rf.id AS rpID "
				+ "FROM " + "t_s_role_function rf," + "t_s_function f " + "WHERE rf.del_status = '0' "
				+ "AND f.del_status = '0' " + "AND rf.function_id = f.ID " + "AND f.parentfunctionid = ?1 "
				+ "AND rf.role_id = '" + roleID + "'";

		List list = new ArrayList();
		// 获取角色一级权限列表
		Query qu = (Query) this.em.createNativeQuery(query);
		List resultList = qu.getResultList();
		for (int i = 0; i < resultList.size(); i++) {
			Object[] object = (Object[]) resultList.get(i);
			list.add(object);
			BigInteger pId = (BigInteger) object[0];
			// 获取二级权限列表
			Query qu1 = (Query) this.em.createNativeQuery(query1);
			qu1.setParameter(1, pId);
			List resultList1 = qu1.getResultList();
			for (int j = 0; j < resultList1.size(); j++) {
				Object[] object1 = (Object[]) resultList1.get(j);
				list.add(object1);
				pId = (BigInteger) object1[0];
				// 获取三级级权限列表
				Query qu2 = (Query) this.em.createNativeQuery(query1);
				qu2.setParameter(1, pId);
				List resultList2 = qu2.getResultList();
				list.addAll(resultList2);
			}
		}

		return list;
	}

	/**
	 * 获取权限列表
	 * 
	 * @return
	 */
	public List getPrivilegeList() {

		logger.debug("获取权限列表");

		String query = "SELECT " + "f.ID AS id," + "f.functionname AS showName," + "f.functioncode AS code,"
				+ "f.functiontype AS type," + "f.functionlevel AS level," + "f.functionorder AS privilegeOrder,"
				+ "f.remark AS remark," + "f.parentfunctionid AS pID,"
				+ "(SELECT fu.functionname FROM t_s_function fu WHERE fu.ID = f.parentfunctionid) AS pshowName,"
				+ "f.mo_menuname AS moName," + "f.iconfile AS　iconfile," + "f.mo_menuicon AS moIcon,"
				+ "f.link AS link " + "FROM " + "t_s_function f "
				+ "WHERE f.del_status = '0' AND f.functionlevel = '1'";
		String query1 = "SELECT " + "f.ID AS id," + "f.functionname AS showName," + "f.functioncode AS code,"
				+ "f.functiontype AS type," + "f.functionlevel AS level," + "f.functionorder AS privilegeOrder,"
				+ "f.remark AS remark," + "f.parentfunctionid AS pID,"
				+ "(SELECT fu.functionname FROM t_s_function fu WHERE fu.ID = f.parentfunctionid) AS pshowName,"
				+ "f.mo_menuname AS moName," + "f.iconfile AS　iconfile," + "f.mo_menuicon AS moIcon,"
				+ "f.link AS link " + "FROM " + "t_s_function f "
				+ "WHERE f.del_status = '0' AND f.parentfunctionid = ?1";

		// 获取一级权限列表
		Query qu = (Query) this.em.createNativeQuery(query);

		List list = new ArrayList();

		List resultList = qu.getResultList();

		for (int i = 0; i < resultList.size(); i++) {
			Object[] object = (Object[]) resultList.get(i);
			list.add(object);
			BigInteger pId = (BigInteger) object[0];
			// 获取二级权限列表
			Query qu1 = (Query) this.em.createNativeQuery(query1);
			qu1.setParameter(1, pId);
			List resultList1 = qu1.getResultList();
			for (int j = 0; j < resultList1.size(); j++) {
				Object[] object1 = (Object[]) resultList1.get(j);
				list.add(object1);
				pId = (BigInteger) object1[0];
				// 获取三级级权限列表
				Query qu2 = (Query) this.em.createNativeQuery(query1);
				qu2.setParameter(1, pId);
				List resultList2 = qu2.getResultList();
				list.addAll(resultList2);
			}
		}
		return list;
	}

	/**
	 * 删除角色权限信息
	 * 
	 * @param values
	 * @return
	 */
	@Transactional
	public void deleteRolePricilege(long roleID) {

		logger.debug("删除角色权限信息");

		String query = "delete from RolePrivilege rp where rp.role.id = ?1";

		this.em.createQuery(query).setParameter(1, roleID).executeUpdate();
	}

	/**
	 * 添加角色权限信息
	 * 
	 * @return
	 */
	@Transactional
	public void addRolePricilege(RolePrivilege rolePrivilege) {

		logger.debug("添加角色权限信息");
		rolePrivilege.setDelStatus((short) 0);

		dslJpaService.setEntityClass(RolePrivilege.class);
		dslJpaService.create(rolePrivilege);
	}

	/**
	 * 添加权限信息
	 * 
	 * @return
	 */
	@Transactional
	public void addPrivilege(Privilege privilege) {

		logger.debug("添加权限信息");
		privilege.setDelStatus((short) 0);

		dslJpaService.setEntityClass(Privilege.class);
		dslJpaService.create(privilege);
	}

	/**
	 * 获取权限详情
	 * 
	 * @return
	 */
	public Privilege getPrivilege(long privilegeId) {

		logger.debug("获取权限详情");

		Privilege result = new Privilege();

		result = this.em.find(Privilege.class, privilegeId);

		return result;
	}

	/**
	 * 修改权限详情
	 * 
	 * @return
	 */
	@Transactional
	public void updatePrivilege(Privilege privilege) {

		logger.debug("修改权限详情");

		String query = "update from Privilege p set p.showName = ?1 ,p.code = ?2 ,p.mobileMenuName = ?3 ,p.type = ?4  ,p.level = ?5 , p.remark = ?6 , p.order = ?7 , p.parent.id = ?8 , p.icon = ?10 ,p.mobileIcon =?11 ,p.link = ?12 where p.id = ?9";

		Privilege parent = privilege.getParent();
		if (parent == null) {
			parent = new Privilege();
		}

		this.em.createQuery(query).setParameter(1, privilege.getShowName()).setParameter(2, privilege.getCode())
				.setParameter(3, privilege.getMobileMenuName()).setParameter(4, privilege.getType())
				.setParameter(5, privilege.getLevel()).setParameter(6, privilege.getRemark())
				.setParameter(7, privilege.getOrder()).setParameter(8, parent.getId())
				.setParameter(9, privilege.getId()).setParameter(10, privilege.getIcon())
				.setParameter(11, privilege.getMobileIcon()).setParameter(12, privilege.getLink()).executeUpdate();
	}

	/**
	 * 删除权限信息
	 * 
	 * @param privilegeId
	 * @return
	 */
	@Transactional
	public void deletePricilege(long privilegeId) {

		logger.debug("删除权限信息");

		StringBuilder query = new StringBuilder("update from Privilege p set p.delStatus = '1' where p.id = ?1");

		this.em.createQuery(query.toString()).setParameter(1, privilegeId).executeUpdate();
	}

	/**
	 * 根据权限等级获取权限列表
	 * 
	 * @param level
	 * @return
	 */
	public List<Privilege> getPrivilegeListByLevel(int level) {

		logger.debug("根据权限等级获取权限列表");

		StringBuilder query = new StringBuilder("select p from Privilege p where p.delStatus != '1' and p.level = ?1");

		// 根据权限等级获取权限列表
		List list = this.em.createQuery(query.toString()).setParameter(1, level).getResultList();
		List<Privilege> privilegeList = new ArrayList<Privilege>();
		for (int i = 0; i < list.size(); i++) {
			Privilege privilege = (Privilege) list.get(i);
			privilegeList.add(privilege);
		}
		return privilegeList;
	}

	/**
	 * 获取菜单导航
	 * 
	 * @param roleID
	 * @return
	 */
	public List<Privilege> getMenuList(long roleID) {

		logger.debug("获取菜单导航");

		StringBuilder query = new StringBuilder(
				"select p from RolePrivilege rp ,Privilege p where rp.delStatus != '1' and p.delStatus != '1' and rp.privilege.id = p.id and p.level = '1' and rp.role.id = ?1 order by p.order");
		StringBuilder query1 = new StringBuilder(
				"select p from RolePrivilege rp ,Privilege p where rp.delStatus != '1' and p.delStatus != '1' and rp.privilege.id = p.id and rp.role.id = ?1 and p.parent.id = ?2 order by p.order");

		// 获取菜单导航
		List list = this.em.createQuery(query.toString()).setParameter(1, roleID).getResultList();

		List<Privilege> menuList = new ArrayList<Privilege>();
		for (int i = 0; i < list.size(); i++) {
			Privilege privilege = (Privilege) list.get(i);
			long pID = privilege.getId();
			List list1 = this.em.createQuery(query1.toString()).setParameter(1, roleID).setParameter(2, pID)
					.getResultList();
			List<Privilege> children = new ArrayList<Privilege>();
			for (int j = 0; j < list1.size(); j++) {
				Privilege childrenResult = (Privilege) list1.get(j);
				children.add(childrenResult);
			}
			privilege.setChildren(children);

			menuList.add(privilege);
		}
		return menuList;
	}

	/**
	 * 获取role
	 */
	public Role getRoleByTenantAndCode(Long tenantId, String code) {
		StringBuilder sql = new StringBuilder(
				"select c from Role c where  c.delStatus != ?1 and c.code = ?2 and c.tenant.id=?3");
		List dataList = this.em.createQuery(sql.toString()).setParameter(1, (short) 1).setParameter(2, code)
				.setParameter(3, tenantId).getResultList();
		Role ct = null;
		if (dataList.size() > 0) {
			ct = (Role) dataList.get(0);
		}
		return ct;
	}

	/**
	 * 获取
	 */
	public Role getRoleByName(String name) {
		StringBuilder sql = new StringBuilder(
				"select c from Role c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3");
		List dataList = this.em.createQuery(sql.toString()).setParameter(1, name).setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();

		Role ct = null;
		if (dataList.size() > 0) {
			ct = (Role) dataList.get(0);
		}

		return ct;
	}

	/**
	 * 获取
	 */
	public Role getRoleByNameFilterId(String name, Long id) {
		StringBuilder sql = new StringBuilder(
				"select c from Role c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3 and c.id!=?4 ");
		List dataList = this.em.createQuery(sql.toString()).setParameter(1, name).setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).setParameter(4, id).getResultList();

		Role ct = null;
		if (dataList.size() > 0) {
			ct = (Role) dataList.get(0);
		}

		return ct;
	}

	/**
	 * 获取
	 */
	public Role getRoleById(Long id) {
		StringBuilder sql = new StringBuilder("select c from Role c where c.id = ?1 and c.delStatus != ?2 ");
		List dataList = this.em.createQuery(sql.toString()).setParameter(1, id).setParameter(2, (short) 1)
				.getResultList();
		Role ct = null;
		if (dataList.size() > 0) {
			ct = (Role) dataList.get(0);
		}
		return ct;
	}

	/**
	 * 赋予移动端权限
	 * 
	 * @param Role
	 *            role 对应角色
	 * @return
	 */
	public void buildMobilePrivileges(Role role) {
		StringBuilder sql = new StringBuilder("insert into t_s_role_function(role_id,function_id,del_status) "
				+ "select " + role.getId().toString() + ",id,0 from t_s_function where" + " functiontype in(11,13)");
		this.jdbcTemplate.execute(sql.toString());
	}

	public Role findPublicByTenant(Long tenantId) {
		StringBuilder hql = new StringBuilder("from Role where tenant.id = :tenantId ").append(" and code = :code ");
		List<Role> roles = this.em.createQuery(hql.toString()).setParameter("tenantId", tenantId)
				.setParameter("code", CommonConstants.ROLE_CODE.WECHAT.getCode()).getResultList();
		return roles == null || roles.size() < 1 ? null : roles.get(0);
	};

}
